package com.alm.token.apinew;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;

import com.alm.token.ConStant;
import com.alm.token.MyApp;
import com.alm.token.utils.CommonUtil;
import com.alm.token.utils.EmptyUtils;
import com.alm.token.utils.LogUtil;
import com.alm.token.utils.SignForInster;
import com.alm.token.utils.SpUtil;
import com.google.gson.Gson;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;

import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okio.Buffer;

/**
 * Created by en on 2019/4/27.
 */

public class LogInterceptor implements Interceptor {

    public static String TAG = "LogInterceptor";
    public static String key = "tmdshuijieshuishabi";
    private static String Content_Type = "application/x-www-form-urlencoded";
    public static String Content_Type_Json = null;//application/json

    @Override
    public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
        Request oldRequest = chain.request();
        Request.Builder newRequestBuild = null;
        String method = oldRequest.method();
        String postBodyString = "";
        if ("POST".equals(method)) {
            RequestBody oldBody = oldRequest.body();
            HashMap<String, String> rootMap = new HashMap<>();
            if (oldBody instanceof FormBody) {
                FormBody.Builder formBodyBuilder = new FormBody.Builder();
                String timestamp = String.valueOf((System.currentTimeMillis()) / 1000);
                formBodyBuilder.add("timestamp", timestamp);
//                formBodyBuilder.add("appVersion", "appVersion");
//                formBodyBuilder.add("appName", "appName");


                for (int i = 0; i < ((FormBody) oldBody).size(); i++) {
                    rootMap.put(((FormBody) oldBody).encodedName(i), ((FormBody) oldBody).encodedValue(i));
                }
                rootMap.put("timestamp", timestamp);
                rootMap.put("user_token", MyApp.Token);

                String sign = new SignForInster().signForInspiry(rootMap, key);
                formBodyBuilder.add("sign", sign);

                newRequestBuild = oldRequest.newBuilder();
                RequestBody formBody = formBodyBuilder.build();
                postBodyString = bodyToString(oldRequest.body());
                postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
                newRequestBuild.post(RequestBody.create(MediaType.parse(EmptyUtils.isNotEmpty(Content_Type_Json) ? Content_Type_Json : "application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
            } else if (oldBody instanceof MultipartBody) {
                MultipartBody oldBodyMultipart = (MultipartBody) oldBody;
                List<MultipartBody.Part> oldPartList = oldBodyMultipart.parts();
                MultipartBody.Builder builder = new MultipartBody.Builder();
                builder.setType(MultipartBody.FORM);
                String timestamp = String.valueOf((System.currentTimeMillis()) / 1000);

                RequestBody requestBody1 = RequestBody.create(MediaType.parse("text/plain"), timestamp);
//                RequestBody requestBody2 = RequestBody.create(MediaType.parse("text/plain"), "appVersion");
//                RequestBody requestBody3 = RequestBody.create(MediaType.parse("text/plain"), "appName");
                for (MultipartBody.Part part : oldPartList) {
                    builder.addPart(part);
                    postBodyString += (bodyToString(part.body()) + "\n");
                }
                postBodyString += (bodyToString(requestBody1) + "\n");
//                postBodyString += (bodyToString(requestBody2) + "\n");
//                postBodyString += (bodyToString(requestBody3) + "\n");
////              builder.addPart(oldBody);  //不能用这个方法，因为不知道oldBody的类型，可能是PartMap过来的，也可能是多个Part过来的，所以需要重新逐个加载进去
                builder.addPart(requestBody1);
//                builder.addPart(requestBody2);
//                builder.addPart(requestBody3);


                newRequestBuild = oldRequest.newBuilder();
                newRequestBuild.post(builder.build());
                LogUtil.e("MultipartBody," + oldRequest.url());
            } else {


                //buffer流
                Buffer buffer = new Buffer();
                oldBody.writeTo(buffer);
                String oldParamsJson = buffer.readUtf8();
                rootMap = new Gson().fromJson(oldParamsJson, HashMap.class);//原始参数
                if (rootMap == null) {
                    rootMap = new HashMap<>();
                }
                FormBody.Builder formBodyBuilder = new FormBody.Builder();
                String timestamp = String.valueOf((System.currentTimeMillis()) / 1000);
                formBodyBuilder.add("timestamp", timestamp);

                rootMap.put("timestamp", timestamp);
                rootMap.put("user_token", MyApp.Token);

                String sign = new SignForInster().signForInspiry(rootMap, key);
                formBodyBuilder.add("sign", sign);

                newRequestBuild = oldRequest.newBuilder();
                RequestBody formBody = formBodyBuilder.build();
                postBodyString = bodyToString(oldRequest.body());
                postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
                newRequestBuild.post(RequestBody.create(MediaType.parse(EmptyUtils.isNotEmpty(Content_Type_Json) ? Content_Type_Json : "application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));

            }
        } else {
            // 添加新的参数
            HttpUrl.Builder commonParamsUrlBuilder = oldRequest.url()
                    .newBuilder()
                    .scheme(oldRequest.url().scheme())
                    .host(oldRequest.url().host())


//                    .addQueryParameter("deviceOs", "deviceOs")
//                    .addQueryParameter("appVersion", "appVersion")
//                    .addQueryParameter("appName", "appName")
                    ;


            newRequestBuild = oldRequest.newBuilder()
                    .method(oldRequest.method(), oldRequest.body())
                    .url(commonParamsUrlBuilder.build());
        }

        Request newRequest;

        if (TextUtils.isEmpty(MyApp.Token) &&
                !TextUtils.isEmpty(SpUtil.getString(MyApp.context, ConStant.TOKEN, ""))) {
            MyApp.Token = SpUtil.getString(MyApp.context, ConStant.TOKEN, "");
        }
        if (MyApp.Token.isEmpty()) {
            newRequest = newRequestBuild
                    .addHeader("Content-Type", EmptyUtils.isNotEmpty(Content_Type_Json) ? Content_Type_Json : Content_Type)
//                    .addHeader("timeZone", TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT))
                    .addHeader("timeZone", getCurrentTimeZone())
                    .addHeader("version", CommonUtil.getVersionName(MyApp.context))
                    .addHeader("appVersion", Build.VERSION.RELEASE)
                    .addHeader("appName", "Android")
                    .addHeader("appUUID", Build.FINGERPRINT)
                    .addHeader("ip", CommonUtil.getIPAddress(MyApp.context))
                    .build();
        } else {
            newRequest = newRequestBuild
                    .addHeader("Content-Type", EmptyUtils.isNotEmpty(Content_Type_Json) ? Content_Type_Json : Content_Type)
//                    .addHeader("timeZone", TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT))
                    .addHeader("timeZone", getCurrentTimeZone())
                    .addHeader("token", MyApp.Token)
                    .addHeader("version", CommonUtil.getVersionName(MyApp.context))
                    .addHeader("appVersion", Build.VERSION.RELEASE)
                    .addHeader("appName", "Android")
                    .addHeader("appUUID", Build.FINGERPRINT)
                    .addHeader("ip", CommonUtil.getIPAddress(MyApp.context))
                    .build();
        }
        Content_Type_Json = null;

//        LogUtil.d("timeZone=" + getCurrentTimeZone());

        long startTime = System.currentTimeMillis();
        okhttp3.Response response = chain.proceed(newRequest);
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        okhttp3.MediaType mediaType = response.body().contentType();
        String content = response.body().string();
        int httpStatus = response.code();
        StringBuilder logSB = new StringBuilder();
        logSB.append("-------start:" + method + "|");
        logSB.append(newRequest.toString() + "\n|");
        logSB.append(method.equalsIgnoreCase("POST") ? "post参数{" + postBodyString + "}\n|" : "");
        logSB.append("httpCode=" + httpStatus + ";Response:" + content + "\n|");
        logSB.append("----------End:" + duration + "毫秒----------");
        LogUtil.d(logSB.toString());
        return response.newBuilder()
                .body(okhttp3.ResponseBody.create(mediaType, content))
                .build();
    }

    private static String bodyToString(final RequestBody request) {
        try {
            final RequestBody copy = request;
            final Buffer buffer = new Buffer();
            if (copy != null)
                copy.writeTo(buffer);
            else
                return "";
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "did not work";
        }
    }


    public static String getCurrentTimeZone() {
        TimeZone tz = TimeZone.getDefault();
        return createGmtOffsetString(true, true, tz.getRawOffset());
    }

    public static String createGmtOffsetString(boolean includeGmt, boolean includeMinuteSeparator, int offsetMillis) {
        int offsetMinutes = offsetMillis / 60000;
        char sign = '+';
        if (offsetMinutes < 0) {
            sign = '-';
            offsetMinutes = -offsetMinutes;
        }
        StringBuilder builder = new StringBuilder(9);
        if (includeGmt) {
            builder.append("GMT");
        }
        builder.append(sign);
        appendNumber(builder, 2, offsetMinutes / 60);
//        if (includeMinuteSeparator) {
//            builder.append(':');
//        }
//        appendNumber(builder, 2, offsetMinutes % 60);
        return builder.toString();
    }

    private static void appendNumber(StringBuilder builder, int count, int value) {
        String string = Integer.toString(value);
//        for (int i = 0; i < count - string.length(); i++) {
//            builder.append('0');
//        }
        builder.append(string);
    }

}
